﻿#region Using Directives

    using System;
    using System.Reflection;
    using System.Web;

#endregion

namespace MarketPulse.Web.Helpers.Base
{
    /// <summary>
    /// This is a class used to manage persisted properties in cookies.
    /// </summary>
    public class CookieManagerBase
    {
        #region Methods

            #region Exposed Methods

                /// <summary>
                /// Gets the value of a set cookie.
                /// </summary>
                /// <param name="propertyType">The property to check the cookie value of.</param>
                /// <returns>The cookie value if set, otherwise null.</returns>
                protected static string GetCookieValue(PropertyInfo propertyType)
                {
                    var cookie = HttpContext.Current.Request.Cookies[GetCookieName(propertyType)];
                    return cookie == null ? null : cookie.Value;
                }

                /// <summary>
                /// Sets the value of a cookie.
                /// </summary>
                /// <param name="propertyType">The property to set the cookie value of.</param>
                /// <param name="value">The value to set the cookie to.</param>
                protected static void SetCookieValue(PropertyInfo propertyType, string value)
                {
                    if (value == null)
                    {
                        HttpContext.Current.Response.SetCookie(new HttpCookie(GetCookieName(propertyType), value)
                        {
                            Expires = DateTime.Now.AddYears(-1)
                        });
                    }
                    else
                    {
                        HttpContext.Current.Response.SetCookie(new HttpCookie(GetCookieName(propertyType), value)
                        {
                            Expires = DateTime.Now.AddDays(GetCookieExpiryDays(propertyType))
                        });
                    }
                }

            #endregion

            #region Private Methods

                /// <summary>
                /// Retrieves the name of a cookie from the CookiePersistence attribute.
                /// </summary>
                /// <param name="propertyType">The Type object for the property to retrieve the name of the cookie from.</param>
                /// <returns>A name to use for setting the cookie of this type.</returns>
                private static string GetCookieName(PropertyInfo propertyType)
                {
                    return ((CookieAttribute)propertyType.GetCustomAttributes(false)[0]).Name;
                }

                /// <summary>
                /// Retrieves the expiry time in days for a cookie from the CookiePersistence attribute.
                /// </summary>
                /// <param name="propertyType">The Type object for the property to retrieve the name of the cookie from.</param>
                /// <returns>The expiry time in days to use for setting the cookie of this type.</returns>
                private static double GetCookieExpiryDays(PropertyInfo propertyType)
                {
                    return ((CookieAttribute)propertyType.GetCustomAttributes(false)[0]).ExpiryDays;
                }
            #endregion

        #endregion

        #region CookieAttribute Class

                /// <summary>
            /// This is a small attribute class used to simplify the creation of persisted properties using cookies.
            /// </summary>
            [AttributeUsage(AttributeTargets.Property)]
            protected class CookieAttribute : Attribute
            {
                /// <summary>
                /// Creates a new instance of the CookiePersistenceAttribute using the specified amount of days for expiry.
                /// </summary>
                /// <param name="expiryDays">The amount of days this cookie should last for.</param>
                public CookieAttribute(double expiryDays)
                {
                    ExpiryDays = expiryDays;
                }

                /// <summary>The expiry time in days for a cookie to last for.</summary>
                public double ExpiryDays { get; private set; }

                /// <summary>The name to use for a cookie.</summary>
                public string Name { get; set; }
            }

        #endregion
    }
}